﻿/***************************************************************
 * 开发人员：网魂小兵@http://www.mozlite.com
 * 
 * 目标标本：4.0.30319.239
 * 
 * 最后修改：2011/11/11 15:13:37
 * ************************************************************/
namespace Mozlite.Common
{
    using System;
    using System.Linq;
    using System.Text;
    using System.Collections.Generic;
    using System.Xml.Serialization;
    using System.Reflection;
    using System.Data;
    using System.Web.Mvc;

    /// <summary>
    /// 权限基类。
    /// </summary>
    [Serializable]
    public abstract class PermissionBase
    {
        /// <summary>
        /// 初始化类<see cref="T:Mozlite.Common.PermissionBase"/>。
        /// </summary>
        protected PermissionBase() { }

        /// <summary>
        /// 获取或设置网站ID。
        /// </summary>
        [XmlIgnore]
        public int SettingsID
        {
            get;
            set;
        }

        /// <summary>
        /// 获取或设置角色ID。
        /// </summary>
        [XmlIgnore]
        public int RoleID
        {
            get;
            set;
        }

        /// <summary>
        /// 获取或设置权限方案ID。
        /// </summary>
        [XmlIgnore]
        public Guid SchemaID
        {
            get;
            set;
        }

        /// <summary>
        /// 从数据库中载入权限。
        /// </summary>
        /// <typeparam name="T">权限类型。</typeparam>
        /// <param name="reader">数据库读取器。</param>
        /// <returns>返回权限。</returns>
        public static T GetPermission<T>(IDataReader reader) where T : PermissionBase, new()
        {
            try
            {
                T permission = Globals.ConvertToObject<T>(reader.GetString("Permissions"));
                permission.RoleID = reader.GetInt32("RoleID");
                permission.SchemaID = reader.GetGuid("SchemaID");
                permission.SettingsID = reader.GetInt32("SettingsID");
                return permission;
            }
            catch { }
            return null;
        }

        /// <summary>
        /// 将权限进行叠加。
        /// </summary>
        /// <param name="permission">要叠加的权限实例对象。</param>
        public void Merger(PermissionBase permission)
        {
            foreach (PropertyInfo info in this.GetType().GetProperties(BindingFlags.Public | BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.GetProperty | BindingFlags.SetProperty))
            {
                if (info.GetCustomAttributes(typeof(XmlIgnoreAttribute), true).Length > 0)
                    continue;
                object v1 = info.GetValue(this, null);
                object v2 = info.GetValue(permission, null);
                object[] attributes = info.GetCustomAttributes(typeof(MergerAttribute), true);
                MergerAttribute attribute;
                if (attributes.Length > 0 && (attribute = (MergerAttribute)attributes[0]) != null)
                {
                    info.SetValue(this, Merger(v1, v2, attribute.Mode, attribute.Seprator), null);
                }
                else
                {
                    info.SetValue(this, Merger(v1, v2, MergerMode.Default, "|"), null);
                }
            }
        }

        private object Merger(object v1, object v2, MergerMode mode, string seprator)
        {
            if (v1 == null)
                return v2;
            if (v2 == null)
                return v1;
            Type type = v1.GetType();
            if (type == typeof(string))
            {
                switch (mode)
                {
                    case MergerMode.Greater:
                        return string.Compare((string)v1, (string)v2, true) >= 0 ? v1 : v2;
                    case MergerMode.Lower:
                        return string.Compare((string)v1, (string)v2, true) <= 0 ? v1 : v2;
                    default:
                        List<string> list = new List<string>();
                        foreach (string v in v1.ToString().Split(new string[] { seprator }, StringSplitOptions.RemoveEmptyEntries))
                        {
                            if (!list.Contains(v))
                                list.Add(v);
                        }
                        foreach (string v in v2.ToString().Split(new string[] { seprator }, StringSplitOptions.RemoveEmptyEntries))
                        {
                            if (!list.Contains(v))
                                list.Add(v);
                        }
                        return list.Join(seprator);
                }
            }
            Type nullableType = Nullable.GetUnderlyingType(type);
            if (nullableType != null)
                type = nullableType;
            if (CommonHelper.IsType(type, typeof(IComparable)))
            {
                if (((IComparable)v1).CompareTo(v2) >= 0)
                {
                    if (type == typeof(bool))
                        return mode == MergerMode.Greater ? v1 : v2;
                    else
                        return mode == MergerMode.Lower ? v2 : v1;
                }
                else
                {
                    if (type == typeof(bool))
                        return mode == MergerMode.Greater ? v2 : v1;
                    else
                        return mode == MergerMode.Lower ? v1 : v2;
                }
            }
            return null;
        }

        /// <summary>
        /// 从客户端获取Form发送的值。
        /// </summary>
        /// <param name="roleID">角色ID。</param>
        /// <param name="form">表单集合。</param>
        /// <returns>返回客户端发送值的实例对象。</returns>
        public static T GetForm<T>(int roleID, FormCollection form) where T : PermissionBase, new()
        {
            T t = new T();
            foreach (PropertyInfo info in typeof(T).GetProperties())
            {
                if (!info.CanWrite || info.GetCustomAttributes(typeof(XmlIgnoreAttribute), true).Length > 0)
                    continue;
                try
                {
                    string valueStr = form[info.Name + "-" + roleID];
                    if (string.IsNullOrEmpty(valueStr))
                        valueStr = null;
                    if (valueStr == null)
                        info.SetValue(t, null, null);
                    else
                    {
                        Type type = info.PropertyType;
                        Type nullableType = Nullable.GetUnderlyingType(type);
                        if (nullableType != null)
                            type = nullableType;
                        object value = Convert.ChangeType(valueStr, Type.GetTypeCode(type));
                        info.SetValue(t, value, null);
                    }
                }
                catch (Exception e) { Logs.Error("Permission Request Error：", "Permissions", EventID.Permissions, e); }
            }
            t.RoleID = roleID;
            return t;
        }
        
        /// <summary>
        /// 判断权限是否允许。
        /// </summary>
        /// <param name="permission">权限。</param>
        /// <returns>返回权限验证结果。</returns>
        public bool IsAllowed(bool? permission)
        {
            if (AppContext.Current.User.IsGlobalAdministrator)
                return true;
            return permission == true;
        }
    }
}